package com.lck.blogmanager.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lck.blogmanager.Enum.*;
import com.lck.blogmanager.entity.*;
import com.lck.blogmanager.exception.BusinessException;
import com.lck.blogmanager.mapper.*;
import com.lck.blogmanager.req.*;
import com.lck.blogmanager.res.*;
import com.lck.blogmanager.service.QuestionService;
import com.lck.blogmanager.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author wyq
 * @version v1.0.0
 * @explain
 * @date 2024/4/7 17:18
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, QuestionEntity> implements QuestionService {

    private final UserMapper userMapper;

    private final TagMapper tagMapper;

    private final AuditMapper auditMapper;

    private final LikeMapper likeMapper;

    private final CollectMapper collectMapper;


    @Override
    public Integer addQuestion(AddQuestionReq req) {
        QuestionEntity question = new QuestionEntity();
        BeanUtils.copyProperties(req,question);
        question.setUserId(SecurityUtils.getUserId())
                .setStatus(BlogStatusEnum.COMMIT.getValue())
                .setViewCount(0)
                .setLikeCount(0)
                .setCollectCount(0)
                .setCreateTime(LocalDateTime.now())
                .setUpdateTime(LocalDateTime.now());
        this.save(question);
        return question.getId();
    }

    @Override
    public void updateQuestion(UpdateQuestionReq req) {
        QuestionEntity entity = this.getBaseMapper().selectById(req.getId());
        if(req.getTotal()!=null&&!StrUtil.isEmpty(req.getTotal())){
            entity.setTotal(req.getTotal());
        }
        if(req.getBody()!=null&&!StrUtil.isEmpty(req.getBody())){
            entity.setBody(req.getBody());
        }
        if(req.getTagId()!=null){
            entity.setTagId(req.getTagId());
        }
        entity.setStatus(QuestionStatusEnum.COMMIT.getValue());
        entity.setUpdateTime(LocalDateTime.now());
        this.saveOrUpdate(entity);
    }

    @Override
    public void deleteQuestion(DeleteQuestionReq req) {
        this.removeById(req.getId());
    }

    @Override
    public Page<PageQuestionRes> pageQuestion(PageQuestionReq req) {
        Page page = new Page(req.getPageNum(),req.getPageSize());
        Page<PageQuestionRes> result = this.getBaseMapper().PageQuestion(req,page);
        return result;

    }

    @Override
    public DetailQuestionRes detailQuestion(Integer questionId) {
        //查问答)
        QuestionEntity question = this.getBaseMapper().selectById(questionId);
        //查关联的用户
        QueryWrapper<UserEntity> userWrapper = new QueryWrapper<>();
        userWrapper.lambda().eq(UserEntity::getId,question.getUserId());
        UserEntity user = userMapper.selectById(question.getUserId());
        //查关联的标签名
        TagEntity tag = tagMapper.selectById(question.getTagId());
        //查审核记录
        QueryWrapper<AuditEntity> auditWrapper = new QueryWrapper<>();
        auditWrapper.lambda().eq(AuditEntity::getRelationId,questionId)
            .eq(AuditEntity::getType,AuditTypeEnum.QUESTION.getValue());
        List<AuditEntity> auditEntities = auditMapper.selectList(auditWrapper);
        DetailQuestionRes res = new DetailQuestionRes();
        BeanUtils.copyProperties(question,res);
        res.setAuditRecords(auditEntities);
        res.setTagName(tag.getTagName());
        res.setUserName(user.getName());
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditQuestion(AuditQuestionReq req) {
        //插入审核记录
        AuditEntity audit = new AuditEntity();
        audit.setType(AuditTypeEnum.QUESTION.getValue());
        audit.setRelationId(req.getId());
        audit.setResult(req.getResult());
        audit.setMessage(req.getReason());
        audit.setCreateTime(LocalDateTime.now());
        auditMapper.insert(audit);
        //改博客的状态
        QuestionEntity question = this.getBaseMapper().selectById(req.getId());
        question.setStatus(req.getResult());
        question.setAuditTime(LocalDateTime.now());
        this.saveOrUpdate(question);
    }

    @Override
    public Page<UserQuestionListRes> userList(UserQuestionListReq req) {
        Page page = new Page(req.getPageNum(),req.getPageSize());
        Page<UserQuestionListRes> info = getBaseMapper().userList(req,page);
        return info;
    }

    @Override
    public Page<PageQuestionRes> userCenterPageQuestion(PageQuestionReq req) {
        Integer userId = SecurityUtils.getUserId();
        Page page = new Page(req.getPageNum(),req.getPageSize());
        Page<PageQuestionRes> result = this.getBaseMapper().UserCenterPageQuestion(req,userId,page);
        return result;
    }

    private void viewQuestion(Integer questionId){
        QuestionEntity question = this.getBaseMapper().selectById(questionId);
        question.setViewCount(question.getViewCount()+1);
        saveOrUpdate(question);
    }

    @Override
    public void likeQuestion(Integer questionId) {
        unviewQuestion(questionId);
        QuestionEntity question = this.getById(questionId);

        Integer userId = SecurityUtils.getUserId();
        QueryWrapper<LikeEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(LikeEntity::getType, LikeRelationTypeEnum.QUESTION.getValue())
                .eq(LikeEntity::getRelationId,questionId)
                .eq(LikeEntity::getUserId,userId);
        LikeEntity entity = likeMapper.selectOne(wrapper);
        if(entity!=null){
            likeMapper.deleteById(entity);
            question.setLikeCount(question.getLikeCount()-1);
            this.saveOrUpdate(question);
        }else {
            LikeEntity like = new LikeEntity();
            like.setType(LikeRelationTypeEnum.QUESTION.getValue());
            like.setUserId(userId);
            like.setRelationId(questionId);
            likeMapper.insert(like);
            question.setLikeCount(question.getLikeCount()+1);
            this.saveOrUpdate(question);
        }
    }

    @Override
    public void collectQuestion(Integer questionId) {
        unviewQuestion(questionId);
        QuestionEntity question = this.getById(questionId);
        Integer userId = SecurityUtils.getUserId();
        QueryWrapper<CollectEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CollectEntity::getType, LikeRelationTypeEnum.QUESTION.getValue())
                .eq(CollectEntity::getRelationId,questionId)
                .eq(CollectEntity::getUserId,userId);
        CollectEntity entity = collectMapper.selectOne(wrapper);
        if(entity!=null){
            collectMapper.deleteById(entity);
            question.setCollectCount(question.getCollectCount()-1);
            this.saveOrUpdate(question);
        }else {
            CollectEntity collect = new CollectEntity();
            collect.setType(LikeRelationTypeEnum.QUESTION.getValue());
            collect.setUserId(userId);
            collect.setRelationId(questionId);
            collectMapper.insert(collect);
            question.setCollectCount(question.getCollectCount()+1);
            this.saveOrUpdate(question);
        }
    }

    @Override
    public QuestionUserDetailRes userDetail(Integer questionId) {
        new Thread(()->viewQuestion(questionId)).start();
        QuestionUserDetailRes res = new QuestionUserDetailRes();
        Integer userId = SecurityUtils.getUserId();
        res.setUserId(userId);
        //先查问答本体
        QuestionEntity question = this.getBaseMapper().selectById(questionId);
        if(question==null){
            throw new BusinessException("博客实体不存在");
        }
        res.setQuestion(question);
        //再查点赞信息
        QueryWrapper<LikeEntity> likeWrapper = new QueryWrapper<>();
        likeWrapper.lambda().eq(LikeEntity::getUserId,userId)
                .eq(LikeEntity::getType, LikeRelationTypeEnum.QUESTION.getValue())
                .eq(LikeEntity::getRelationId,questionId);
        Long likeCount = likeMapper.selectCount(likeWrapper);
        if(likeCount>0){
            res.setIsLike(CommonEnum.YES.getValue());
        }else {
            res.setIsLike(CommonEnum.NO.getValue());
        }
        //收藏信息
        QueryWrapper<CollectEntity> countWrapper = new QueryWrapper<>();
        countWrapper.lambda().eq(CollectEntity::getUserId,userId)
                .eq(CollectEntity::getType, LikeRelationTypeEnum.QUESTION.getValue())
                .eq(CollectEntity::getRelationId,questionId);
        Long collectCount = collectMapper.selectCount(countWrapper);
        if(collectCount>0){
            res.setIsCollect(CommonEnum.YES.getValue());
        }else {
            res.setIsCollect(CommonEnum.NO.getValue());
        }
        return res;
    }


    private void unviewQuestion(Integer questionId){
        QuestionEntity question = this.getBaseMapper().selectById(questionId);
        question.setViewCount(question.getViewCount()-1);
        saveOrUpdate(question);
    }

}
